package dx.util;

import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 时间格式化处理工具类
 * copy by duanx 2020/12/20
 *@description： 时间日期字符串互换
 *@classname: TimeString
 *@author: duanx
 *@date: 2020/12/20 18:19
 **/
public class TimeStringUtil {

    /** 锁对象 */
    private static final Object LOCK_OBJ = new Object();
    private static Logger logger = LoggerFactory.getLogger(TimeStringUtil.class);

    /** 存放不同的日期模板格式的sdf的Map */
    private static Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<>();

    /**
     * 返回一个ThreadLocal的sdf,每个线程只会new一次sdf
     *
     * @param pattern 格式
     * @return 格式模板
     */
    private static SimpleDateFormat getSdf(final String pattern) {
        ThreadLocal<SimpleDateFormat> threadLocal = sdfMap.get(pattern);

        // 此处的双重判断和同步是为了防止sdfMap这个单例被多次put重复的sdf
        if (threadLocal == null) {
            synchronized (LOCK_OBJ) {
                threadLocal = sdfMap.get(pattern);
                if (threadLocal == null) {
                    // 只有Map中还没有这个pattern的sdf才会生成新的sdf并放入map
                    // 这里是关键,使用ThreadLocal<SimpleDateFormat>替代原来直接new SimpleDateFormat
                    threadLocal = ThreadLocal.withInitial(() -> {
                        logger.debug("当前线程-==>" + Thread.currentThread().getName() + " 初始化时间格式-==>" + pattern);
                        return new SimpleDateFormat(pattern);
                    });
                    sdfMap.put(pattern, threadLocal);
                }
            }
        }
        logger.debug("生成一个新的转换格式-==>" + pattern);
        return threadLocal.get();
    }

    /**
     * 日期转换成字符串
     * 是用ThreadLocal<SimpleDateFormat>来获取SimpleDateFormat,这样每个线程只会有一个SimpleDateFormat
     *
     * @param date 日期
     * @param pattern 格式
     * @return 字符
     */
    @NotNull
    public static String dateFormatToString(Date date, String pattern) {
        return getSdf(pattern).format(date);
    }

    /**
     * 字符穿转换成日期格式
     * @param dateStr 字符串
     * @param pattern 格式
     * @return 日期
     * @throws ParseException 转换异常
     */
    public static Date stringParseToDate(String dateStr, String pattern) throws ParseException {
        return getSdf(pattern).parse(dateStr);
    }


    public static void main(String[] args) {
        Date date = new Date();
        System.out.println(dateFormatToString(date,"YYMMddHHmm"));
        String str = "2021-01-31";
        try {
            System.out.println(stringParseToDate(str,"YYYY-MM-dd"));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
